package com.lagou.handler;

import com.lagou.request.RpcRequest;
import com.lagou.server.ServerStarter;
import com.lagou.zk.ServerInfoVO;
import com.lagou.zk.ZkHelper;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Component
public class UserServerHandler extends ChannelInboundHandlerAdapter implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 判断是否符合约定，符合则调用本地方法，返回数据
        if (msg instanceof RpcRequest) {
            // 获取消息对象
            RpcRequest request = (RpcRequest) msg;
            // 获取服务类名
            String className = request.getClassName();
            // 获取服务方法名
            String methodName = request.getMethodName();
            // 按Bean名约定，将类名首字母转小写，得到Bean名
            String beanName = className.substring(0, 1).toLowerCase() + className.substring(1);
            // 获取Bean对象
            Object serviceBean = applicationContext.getBean(beanName);
            // 获取方法
            Method method = serviceBean.getClass().getMethod(methodName, request.getParameterTypes());

            long t1 = System.currentTimeMillis();
            // 调用方法
            Object result = method.invoke(serviceBean, request.getParameters());
            // 向Client输出结果 "success"
            ctx.writeAndFlush(result);
            // 计算响应耗时，sayHello方法中增加等待随机时间
            long timeSpend = System.currentTimeMillis() - t1;
            ServerInfoVO serverInfo = ServerStarter.getServerInfo();
            // 向ZK更新当前服务的响应时间
            ZkHelper.updateServerSpeed(serverInfo.getServerName(), timeSpend);
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        UserServerHandler.applicationContext = applicationContext;
    }
}
